package com.vdg.lockapp.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.drm.DrmStore.Action;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

import com.vdg.data.AppInformation;
import com.vdg.data.SettingData;
import com.vdg.data.SettingData.LOCK_TYPE;
import com.vdg.lockapp.HackActivity;
import com.vdg.lockapp.MainActivity;
import com.vdg.lockapp.PassCodeActivity;
import com.vdg.lockapp.R;
import com.vdg.lockapp.PassCodeActivity.PASS_CODE_ACTION_TYPE;
import com.vdg.lockapp.listener.OnLoadAppInforListener;
import com.vdg.util.Utilities;

public class LockService extends Service {
	private ServiceNotification mServiceNotification = null;
	String lastFrontAppPkg;
	private static final int REQ_ENTER_PATTERN = 2;
	private ArrayList<String> mListLockPkg;
	private static final String TAG = "LockService";
	private final IBinder mBinder = new LocalBinder();
	protected static int SERVICE_NOTIFICATION = 1;
	private String mAppUnlocked = "";
	// private String mAppLocking;
	private Handler mHandler = new Handler();
	public static final String APP_LOCK_PACKAGE_NAME = "package_name";
	// private ArrayList<String> mAppForeGround = new ArrayList<String>();
	private SettingData mSettingData;
	private OnLoadAppInforListener mOnLoadAppInforListener;
	protected PendingIntent mPAlarmIntent;
	protected Intent mAlarmIntent = new Intent(RECHECK_ALARM);
	private static final String RECHECK_ALARM = "com.vdg.lockapp.service.RECHECK_ALARM";
	private BroadcastReceiver mAlarmReceiver = new ReCheckAlarmReceiver();

	private class ReCheckAlarmReceiver extends BroadcastReceiver {
		public void onReceive(Context ctx, Intent i) {
			checkLock();
		}
	}

	BroadcastReceiver mPackageChangeReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			// TODO Auto-generated method stub
			Log.v(TAG, "application change");
			if (intent.getAction().equals(Intent.ACTION_UNINSTALL_PACKAGE)
					|| intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) {
				Uri uri = intent.getData();
				String pkg = uri != null ? uri.getSchemeSpecificPart() : null;
				Utilities.removeAppLocker(pkg, LockService.this);
				removeLockApp(pkg);
			}
			PackageManager pm = getPackageManager();
			getListAppInfor(pm);
		}
	};

	public void unRegisOnLoaddAppInforListener() {
		mOnLoadAppInforListener = null;
	}

	public void queryAppData(OnLoadAppInforListener listener) {
		mOnLoadAppInforListener = listener;
		(new Thread() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				PackageManager pm = getPackageManager();
				getListAppInfor(pm);
				super.run();
			}
		}).start();
	}

	private void getListAppInfor(PackageManager pm) {
		final ArrayList<AppInformation> listAppInfor = new ArrayList<AppInformation>();
		final ArrayList<String> listSelected = new ArrayList<String>();
		Intent intent = new Intent(Intent.ACTION_MAIN, null);

		List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);

		for (ResolveInfo rInfo : list) {
			String pkg = rInfo.activityInfo.applicationInfo.packageName;
			if (pm.getLaunchIntentForPackage(pkg) == null
					|| pkg.equals(LockService.this.getPackageName())
					|| checkContain(listAppInfor, pkg)) {
				Log.v(TAG, "package name check =" + pkg);
				continue;
			}
			// String label =
			// rInfo.activityInfo.applicationInfo.loadLabel(pm).toString();
			// arrayList.add(new AppEntry(label, activityName, pkg, null));
			// PackageInfo=rInfo.activityInfo;
			// }
			// for (PackageInfo infor : packs) {
			// if (infor.versionName == null || (infor == null)
			// || infor.applicationInfo.icon == 0
			// || infor.packageName.equals(getPackageName())) {
			// continue;
			// }
			// String name = infor.applicationInfo.loadLabel(
			// LockService.this.getPackageManager()).toString();
			String name = rInfo.activityInfo.applicationInfo.loadLabel(
					this.getPackageManager()).toString();
			// Log.v(TAG, "name = " + name + " package = "
			// + rInfo.activityInfo.packageName + " flag = "
			// + rInfo.activityInfo.applicationInfo.flags);
			// if (!isSystemPackage(infor)) {
			// boolean isLocked = false;
			// {
			// if (Utilities.isLocked(rInfo.activityInfo.packageName, this)) {
			// isLocked = true;
			// listSelected.add(rInfo.activityInfo.packageName);
			// addLockApp(rInfo.activityInfo.packageName);
			// }
			// }
			// listAppInfor.add(new
			// AppInformation(rInfo.activityInfo.applicationInfo,
			// isLocked, name));
			// } else {
			// if (infor.applicationInfo.flags != 8961605
			// && infor.applicationInfo.flags != 8961541
			// && infor.applicationInfo.flags != 8961613
			// && infor.applicationInfo.flags != 8437317
			// && infor.applicationInfo.flags != 8961637) {
			boolean isLocked = false;
			if (Utilities.isLocked(pkg, this)) {
				isLocked = true;
				listSelected.add(pkg);
				addLockApp(pkg);
			}
			AppInformation appInfor = new AppInformation(
					rInfo.activityInfo.applicationInfo, isLocked, name);
			listAppInfor.add(appInfor);
			// }
			// }
		}
		if (listAppInfor.size() > 0) {
			Collections.sort(listAppInfor);
		}
		if (mOnLoadAppInforListener != null) {
			mHandler.post(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					mOnLoadAppInforListener.onLoadSucessFully(listAppInfor,
							listSelected);
				}
			});
		}
	}

	public boolean checkContain(ArrayList<AppInformation> listAppInfor,
			String packageName) {
		for (AppInformation infor : listAppInfor) {
			if (infor.packageName.equals(packageName))
				return true;
		}
		return false;
	}

	public class LocalBinder extends Binder {
		public LockService getService() {
			// Return this instance of LocalService so clients can call public
			// methods
			return LockService.this;
		}
	}

	public synchronized void unlockApp(String packageName) {
		synchronized (mAppUnlocked) {
			Log.v(TAG, "start activity logacc " + packageName + "  running "
					+ isProcessRunning(mAppUnlocked));
			if (isProcessRunning(packageName)
					&& !packageName.equals(LockService.this.getPackageName())) {
				mAppUnlocked = packageName;
			}
		}
	}

	public boolean isProcessRunning(String process) {
		ActivityManager activityManager = (ActivityManager) getApplicationContext()
				.getSystemService(ACTIVITY_SERVICE);
		List<RunningAppProcessInfo> appProcesses = activityManager
				.getRunningAppProcesses();
		for (int i = 0; i < appProcesses.size(); i++) {
			if (((String) appProcesses.get(i).pkgList[0]).equals(process)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return mBinder;
	}

	public synchronized void addLockApp(ArrayList<String> listLockPkg) {
		this.mListLockPkg.addAll(listLockPkg);
	}

	public synchronized void addLockApp(String applock) {
		if (!mListLockPkg.contains(applock)) {
			mListLockPkg.add(applock);
		}
	}

	public synchronized void removeLockApp(String applock) {
		if (mListLockPkg.contains(applock)) {
			mListLockPkg.remove(applock);
		}
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		mListLockPkg = Utilities.getListAppLocked(this);
		// Log.v(TAG, "start service lockapp");
		// setupTimer();
		mServiceNotification = ServiceNotification.getInstance();
		updateServiceNotification();
		mPAlarmIntent = PendingIntent.getBroadcast(this, 0, mAlarmIntent,
				PendingIntent.FLAG_UPDATE_CURRENT);
		registerReceiver(mAlarmReceiver, new IntentFilter(RECHECK_ALARM));
		startCheckLockAlarm();
		IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
		intentFilter.addAction(Intent.ACTION_PACKAGE_INSTALL);
		intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
		intentFilter.addAction(Intent.ACTION_UNINSTALL_PACKAGE);
		intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
		intentFilter.addDataScheme("package");
		registerReceiver(mPackageChangeReceiver, intentFilter);
	}

	private boolean appUnlockIsForground(String currentRuning) {
		if (!mAppUnlocked.equals("")) {
			// while (!isAppForground(mAppUnlocked)
			// && isAppForground(LockService.this.getPackageName())) {
			// try {
			// Thread.sleep(500);
			// } catch (InterruptedException e) {
			// e.printStackTrace();
			// }
			// }
			if (isAppForground(LockService.this.getPackageName())) {
				return true;
			}
		}
		return false;
	}

	// public void setupTimer() {
	// Timer timer = new Timer();
	// timer.scheduleAtFixedRate(new TimerTask() {
	// public synchronized void run() {
	// synchronized (mAppUnlocked) {
	// waitAppUnlockToForground();
	// ActivityManager activityManager = (ActivityManager)
	// getApplicationContext()
	// .getSystemService(ACTIVITY_SERVICE);
	// List<RunningAppProcessInfo> appProcesses = activityManager
	// .getRunningAppProcesses();
	// mAppForeGround.clear();
	// mAppForeGround = new ArrayList<String>();
	// for (RunningAppProcessInfo appProcess : appProcesses) {
	// // try {
	// if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND
	// && !((String) appProcess.pkgList[0])
	// .equals(LockService.this
	// .getPackageName())) {
	//
	// mAppForeGround.add((String) appProcess.pkgList[0]);
	// if (mListLockPkg
	// .contains((String) appProcess.pkgList[0])) {
	// if (!(!mAppUnlocked.equals("")
	// && mAppUnlocked
	// .equals((String) appProcess.pkgList[0]) && mAppForeGround
	// .contains(mAppUnlocked))) {
	// startLockActivity((String) appProcess.pkgList[0]);
	// } else {
	// Log.v(TAG, "app background 1 "
	// + mAppUnlocked);
	// // wait app goto background
	// while (isAppForground(mAppUnlocked)) {
	// try {
	// Log.v(TAG, "wait background");
	// Thread.sleep(100);
	// } catch (InterruptedException e) {
	// e.printStackTrace();
	// }
	// }
	// if (!isAppForground(mAppUnlocked)) {
	// mAppUnlocked = "";
	// }
	// break;
	// }
	// }
	// }
	// }
	// }
	// }
	// }, 0, 200);
	// }
	private boolean isAppForground(String packageName) {
		ActivityManager activityManager = (ActivityManager) getApplicationContext()
				.getSystemService(ACTIVITY_SERVICE);
		List<ActivityManager.RunningTaskInfo> taskInfo = activityManager
				.getRunningTasks(1);

		String currentPackageRunning = taskInfo.get(0).topActivity
				.getPackageName();
		if (currentPackageRunning.equals(packageName)) {
			return true;
		}
		return false;
	}

	// private boolean isAppForground(String packageName) {
	// ActivityManager mActivityManager = (ActivityManager)
	// getSystemService(Context.ACTIVITY_SERVICE);
	// List<RunningAppProcessInfo> l = mActivityManager
	// .getRunningAppProcesses();
	// Iterator<RunningAppProcessInfo> i = l.iterator();
	// while (i.hasNext()) {
	// RunningAppProcessInfo info = i.next();
	// if (info.pkgList[0].equals(packageName)
	// && info.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
	// return true;
	// }
	// }
	// return false;
	// }

	protected void updateServiceNotification() {
		Notification n = new Notification(R.drawable.ic_launcher, "LockApp",
				System.currentTimeMillis());
		n.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;

		Intent notificationIntent = new Intent(this, MainActivity.class);
		notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
		n.contentIntent = PendingIntent.getActivity(this, 0,
				notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
		n.setLatestEventInfo(this, "Applocker", "Applocker enable",
				n.contentIntent);
		mServiceNotification.showNotification(this, SERVICE_NOTIFICATION, n);
	}

	private void startLockActivity(String appPackage) {
		mSettingData = SettingData.getInstance(this);
		if (!mSettingData.getLockType().equals(LOCK_TYPE.PASS_CODE)) {
			if (mSettingData.getLockType().equals(LOCK_TYPE.FAKE_FORCE_CLOSE)) {
				gotoHome();
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			Intent intent = new Intent(LockService.this, HackActivity.class);
			intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
			intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
			intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			intent.putExtra(APP_LOCK_PACKAGE_NAME, appPackage);
			intent.putExtra(PassCodeActivity.PASS_CODE_ACTION,
					PASS_CODE_ACTION_TYPE.UNLOCK_ACTION.toString());
			LockService.this.startActivity(intent);
		} else {
			Intent intent = new Intent(this, PassCodeActivity.class);
			intent.putExtra(LockService.APP_LOCK_PACKAGE_NAME, appPackage);
			intent.putExtra(PassCodeActivity.PASS_CODE_ACTION,
					PASS_CODE_ACTION_TYPE.UNLOCK_ACTION.toString());
			intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
			intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
			startActivity(intent);
		}
	}

	private void startCheckLockAlarm() {
		Thread thread = new Thread() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				while (true) {
					checkLock();
					try {
						sleep(500);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		};
		thread.start();
		// ((AlarmManager) getSystemService(Context.ALARM_SERVICE)).set(
		// AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 500,
		// mPAlarmIntent);nn
	}

	private void checkLock() {
		synchronized (mAppUnlocked) {
			Log.v(TAG, " mAppUnlocked=" + mAppUnlocked);
			ActivityManager activityManager = (ActivityManager) getApplicationContext()
					.getSystemService(ACTIVITY_SERVICE);
			List<ActivityManager.RunningTaskInfo> taskInfo = activityManager
					.getRunningTasks(1);

			String currentPackageRunning = taskInfo.get(0).topActivity
					.getPackageName();
			if (!(currentPackageRunning).equals(LockService.this
					.getPackageName())) {
				if (!mAppUnlocked.equals("")) {
					// }
					if (isAppForground(mAppUnlocked)
							&& !isAppForground(LockService.this
									.getPackageName())) {
						while (isAppForground(mAppUnlocked)) {
							try {
								Log.v(TAG, "wait background");
								Thread.sleep(1000);
							} catch (InterruptedException e) {
								e.printStackTrace();
							}
						}
						mAppUnlocked = "";
					} else {
						return;
					}
				} else {
					if (mListLockPkg.contains(currentPackageRunning)) {
						startLockActivity(currentPackageRunning);
					}
				}
			}
		}
		// try {
		// if (!(currentPackageRunning).equals(LockService.this
		// .getPackageName())) {
		// // Log.v(TAG,
		// // "app runing - = "
		// // + currentPackageRunning
		// // + "    "
		// // + Utilities.getAppName(LockService.this,
		// // currentPackageRunning));
		// if (mListLockPkg.contains(currentPackageRunning)) {
		// if (!(!mAppUnlocked.equals("") && mAppUnlocked
		// .equals(currentPackageRunning))) {
		// startLockActivity(currentPackageRunning);
		// } else {
		// // Log.v(TAG, "app background 1 " + mAppUnlocked);
		// // wait app goto background
		// while (isAppForground(mAppUnlocked,
		// currentPackageRunning)) {
		// try {
		// Log.v(TAG, "wait background");
		// Thread.sleep(1000);
		// } catch (InterruptedException e) {
		// e.printStackTrace();
		// }
		// }
		// // Log.v(TAG, "app is background1");
		// if (!isAppForground(mAppUnlocked, currentPackageRunning)) {
		// // Log.v(TAG, "app is background");
		// mAppUnlocked = "";
		// }
		// }
		// }
		// }
		// }
	}

	// private void checkLock() {
	// synchronized (mAppUnlocked) {
	// Log.v(TAG, " mAppUnlocked=" + mAppUnlocked);
	// waitAppUnlockToForground();
	// ActivityManager activityManager = (ActivityManager)
	// getApplicationContext()
	// .getSystemService(ACTIVITY_SERVICE);
	// List<RunningAppProcessInfo> appProcesses = activityManager
	// .getRunningAppProcesses();
	// mAppForeGround.clear();
	// mAppForeGround = new ArrayList<String>();
	// for (RunningAppProcessInfo appProcess : appProcesses) {
	// // try {
	// if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND
	// && !((String) appProcess.pkgList[0])
	// .equals(LockService.this.getPackageName())) {
	// Log.v(TAG, "app runing - = "
	// + (String) appProcess.pkgList[0]
	// + "    "
	// + Utilities.getAppName(LockService.this,
	// (String) appProcess.pkgList[0]));
	// mAppForeGround.add((String) appProcess.pkgList[0]);
	// if (mListLockPkg.contains((String) appProcess.pkgList[0])) {
	// if (!(!mAppUnlocked.equals("")
	// && mAppUnlocked
	// .equals((String) appProcess.pkgList[0]) && mAppForeGround
	// .contains(mAppUnlocked))) {
	// startLockActivity((String) appProcess.pkgList[0]);
	// } else {
	// Log.v(TAG, "app background 1 " + mAppUnlocked);
	// // wait app goto background
	// while (isAppForground(mAppUnlocked)) {
	// try {
	// Log.v(TAG, "wait background");
	// Thread.sleep(500);
	// } catch (InterruptedException e) {
	// e.printStackTrace();
	// }
	// }
	// Log.v(TAG, "app is background1");
	// mAppUnlocked = "";
	// break;
	// }
	// }
	// }
	// }
	// if (!isAppForground(mAppUnlocked)) {
	// Log.v(TAG, "app is background");
	// mAppUnlocked = "";
	// }
	// }
	// }

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		Log.v(TAG, "ondestroy services");
		unregisterReceiver(mPackageChangeReceiver);
		unregisterReceiver(mAlarmReceiver);
		super.onDestroy();
	}

	private void gotoHome() {
		Intent homeIntent = new Intent(Intent.ACTION_MAIN);
		homeIntent.addCategory(Intent.CATEGORY_HOME);
		homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		startActivity(homeIntent);
	}
}
